package com.access.db;

import access.model.AccessPolicy;
import access.db.SQLServer;
import java.util.HashMap;
import java.util.Iterator;


/**
 * Created by koujx on 2016/7/18.
 */
public class PolicyCacheManager {
    public final static long cacheTime = 3600000;
    private static HashMap cacheMap = new HashMap();
    private final static int cacheSize = 10;

    private PolicyCacheManager() {
        super();
    }

    public synchronized static AccessPolicy getAccessPolicy(String dataId, String operation) {
        String key = dataId + ";" + operation;
        PolicyCache policyCache = getCache(key, true);
        return policyCache.getPolicy();
    }

    public synchronized static AccessPolicy getAccessPolicy(String apiName) {
        String key = apiName;
        PolicyCache policyCache = getCache(key, false);
        return policyCache.getPolicy();
    }

    //得到缓存策略
    public synchronized static PolicyCache getCache(String key, boolean flag) {
        if (hasCache(key)) {
            return (PolicyCache) cacheMap.get(key);
        } else {
            AccessPolicy accessPolicy;
            double ratio;
            if (flag) {
                String dataId = key.split(";")[0];
                String operation = key.split(";")[1];
                accessPolicy = SQLServer.getAccessPolicy(dataId, operation);
                ratio = 0;
            } else {
                String apiName = key;
                accessPolicy = SQLServer.getApiAccessPolicy(apiName);
                ratio = 0;
            }
            PolicyCache policyCache = new PolicyCache(accessPolicy, System.currentTimeMillis(), ratio, true);
            putCache(key, policyCache);
            return policyCache;
        }
    }

    //判断策略是否在缓存中
    public synchronized static boolean hasCache(String key) {
        return cacheMap.containsKey(key);
    }

    //清除全部缓存策略
    public synchronized static void clearAllCaches() {
        cacheMap.clear();
    }

    //清除指定的缓存策略
    public synchronized static void clearOneCache(String key) {
        if (hasCache(key)) {
            cacheMap.remove(key);
        }
    }

    //从数据库中载入缓存
    public synchronized static void putCache(String key, PolicyCache cache) {
        if (cacheMap.size() < cacheSize || hasCache(key)) {
            cacheMap.put(key, cache);
        } else {
            double min = 1;
            String clearKey = null;
            Iterator i = cacheMap.entrySet().iterator();
            while (i.hasNext()) {
                HashMap.Entry entry = (HashMap.Entry) i.next();
                String currentKey = (String) entry.getKey();
                PolicyCache currentPC = (PolicyCache) entry.getValue();
                if (currentPC.updateWeight() < min) {
                    clearKey = currentKey;
                    min = currentPC.getWeight();
                }
            }
            clearOneCache(clearKey);
            cacheMap.put(key, cache);
        }
    }


    //重写载入缓存信息
    public static void putCacheInfo(String key, PolicyCache policyCache) {
        PolicyCache cache = policyCache;
        cache.setCounts(cache.getCounts() + 1);
        cacheMap.put(key, cache);
    }

    //获取缓存中的大小
    public static int getCacheSize() {
        return cacheMap.size();
    }
}
